package pers.kw.config.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class RabbitTemplateConfig {

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        //1、new出RabbitTemplate对象
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        //2、将connectionFactory设置到RabbitTemplate对象中
        rabbitTemplate.setConnectionFactory(connectionFactory);

        //------------消息可靠投递处理------------
        //3、设置confirm回调
        rabbitTemplate.setConfirmCallback(confirmCallback());
        //4、设置return回调
        rabbitTemplate.setReturnCallback(returnCallback());

        //5、设置mandatory为true
        rabbitTemplate.setMandatory(true);
        //6、返回RabbitTemplate对象即可
        return rabbitTemplate;
    }

    /**
     * 消息投递交换机失败，回调处理
     */
    public RabbitTemplate.ConfirmCallback confirmCallback() {
        return (correlationData, ack, cause) -> {
            if (correlationData == null) return;
            String msgId = correlationData.getId();
            if (ack) {
                log.info("消息发送到Exchange成功!! msgId = {}", msgId);
            } else {
                //todo 投递失败，进入redis或死信队列，人工补偿
                log.info("消息发送到Exchange失败!! msgId = {}", msgId);
            }
        };
    }

    /**
     * 消息路由到队列失败，回调处理
     */
    public RabbitTemplate.ReturnCallback returnCallback() {
        return (message, replyCode, replyText, exchange, routingKey) -> {
            //todo 投递失败，进入redis或死信队列，人工补偿
            log.info("消息未路由到队列");
            log.info("return：消息为：{}", new String(message.getBody()));
            log.info("return：交换机为：{}", exchange);
            log.info("return：路由为：{}", routingKey);
        };
    }
}
